/*
 * H264ProgramStreamPlayer.cpp
 *
 *  Created: 2013-07-07
 *   Author: terry
 */

#include "stdafx.h"
#include "H264ProgramStreamPlayer.h"
#include <assert.h>


unsigned char s_hkStreamHeader[40] = {
    0x49, 0x4D, 0x4B, 0x48, 0x01, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00
};

bool startWithHKHeader(const BYTE* pBuffer, int length)
{
    if (length < 40)
    {
        return false;
    }
    
    bool found = false;
    if (pBuffer[0] == s_hkStreamHeader[0] &&
        pBuffer[1] == s_hkStreamHeader[1] &&
        pBuffer[2] == s_hkStreamHeader[2] &&
        pBuffer[3] == s_hkStreamHeader[3])
    {
        int ret = memcmp(pBuffer, s_hkStreamHeader, 40);
        found = (ret == 0);
    }

    return found;
}



H264ProgramStreamPlayer::H264ProgramStreamPlayer()
{
    m_analyzer.setSink(this);
}

H264ProgramStreamPlayer::~H264ProgramStreamPlayer()
{

}

bool H264ProgramStreamPlayer::inputData(const unsigned char* buffer, size_t length)
{
    if (length == 0)
    {
        return false;
    }

    if (startWithHKHeader(buffer, length))
    {
        return m_analyzer.inputData(buffer + 40, length - 40);
    }

    return m_analyzer.inputData(buffer, length);
}

void H264ProgramStreamPlayer::resetBuffer()
{
    m_analyzer.clear();
}

void H264ProgramStreamPlayer::writePacket(NaluPacket& packet)
{
    switch (packet.type)
    {
    case NaluPacket::NALU_PPS:
    case NaluPacket::NALU_SEI:
        m_buffer.write(packet.data, packet.length);
        break;
    case NaluPacket::NALU_IFRAME:
        m_buffer.write(packet.data, packet.length);
        m_decode.inputData(m_buffer.getReadPtr(), m_buffer.readable());
        m_buffer.clear();
        break;
    case NaluPacket::NALU_NULL:
        if (m_buffer.readable() > 0)
        {
            m_buffer.write(packet.data, packet.length);
        }
        break;
    default:
        {
            if (m_buffer.readable())
            {
                m_decode.inputData(m_buffer.getReadPtr(), m_buffer.readable());
                m_buffer.clear();
            }

            if (packet.prefix == 4)
            {
                m_decode.inputData(packet.data, packet.length);
            }
            else
            {
                //WinTrace("prefix = 3. length: %d, type:%d\n", packet.length, packet.type);
            }
        }
        break;
    }
}